package org.zs.miracle.service.resources.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zs.miracle.common.base.dto.BaseManyLongIdDTO;
import org.zs.miracle.common.exception.UserFriendlyException;
import org.zs.miracle.common.util.ModelMapperUtil;
import org.zs.miracle.common.util.tree.ITreeNode;
import org.zs.miracle.common.util.tree.TreeUtil;
import org.zs.miracle.entity.enums.ResourcesTypeEnum;
import org.zs.miracle.entity.system.ResourcesEntity;
import org.zs.miracle.entity.system.RoleResourcesEntity;
import org.zs.miracle.mapper.ResourcesMapper;
import org.zs.miracle.mapper.RoleResourcesMapper;
import org.zs.miracle.service.resources.IResourcesService;
import org.zs.miracle.service.resources.model.dto.AddResourcesInputDTO;
import org.zs.miracle.service.resources.model.dto.EditResourcesDTO;
import org.zs.miracle.service.resources.model.dto.SetResourcesStateDTO;
import org.zs.miracle.service.resources.model.vo.ResourcesTreeVo;
import org.zs.miracle.service.resources.model.vo.ResourcesVo;

@AllArgsConstructor
@Service
public class ResourcesServiceImpl implements IResourcesService {
  
  ResourcesMapper resourcesRepository;
  RoleResourcesMapper roleResourcesRepository;
  
  @Transactional(rollbackFor = Exception.class)
  @Override
  public Boolean delResources(BaseManyLongIdDTO inputDTO) {
    
    // 删除资源关联角色中间表数据
    roleResourcesRepository.delete(Wrappers.<RoleResourcesEntity>lambdaQuery()
        .in(RoleResourcesEntity::getResourcesId, inputDTO.getIds()));
    // 删除资源
    resourcesRepository.deleteByIds(inputDTO.getIds());
    return true;
  }
  
  @Override
  public Boolean addResources(AddResourcesInputDTO inputDTO) {
    
    // 判断资源编码是否重复
    if (resourcesRepository.exists(Wrappers.<ResourcesEntity>lambdaQuery()
        .eq(ResourcesEntity::getCode, inputDTO.getCode()))) {
      throw new UserFriendlyException("资源编码已存在,换一个吧");
    }
    
    // DTO转换实体
    ResourcesEntity resourcesEntity =
        ModelMapperUtil.map(inputDTO, ResourcesEntity.class, (source, target) -> {
          target.setSort(source.getOrder());
          target.setIsShow(source.getShow());
        });
    
    // 插入数据库
    resourcesRepository.insert(resourcesEntity);
    
    return true;
  }
  
  @Override
  public Boolean editResources(EditResourcesDTO inputDTO) {
    
    // 数据库中的数据
    ResourcesEntity resourcesEntity = resourcesRepository.selectById(inputDTO.getId());
    
    // 修改了资源编码需要判断是否重复
    if (!resourcesEntity.getCode().equals(inputDTO.getCode())) {
      // 判断资源编码是否重复
      if (resourcesRepository.exists(Wrappers.<ResourcesEntity>lambdaQuery()
          .ne(ResourcesEntity::getCode, resourcesEntity.getCode())
          .eq(ResourcesEntity::getCode, inputDTO.getCode()))) {
        
        throw new UserFriendlyException("资源编码已存在,换一个吧!");
      }
    }
    
    // DTO转换实体
    ResourcesEntity updateEntity =
        ModelMapperUtil.map(inputDTO, ResourcesEntity.class, (source, target) -> {
          target.setSort(source.getOrder());
          target.setIsShow(source.getShow());
        });
    
    // 执行更新
    this.resourcesRepository.updateById(updateEntity);
    
    return true;
  }
  
  @Override
  public Boolean setState(SetResourcesStateDTO inputDTO) {
    
    ResourcesEntity updateEntity =
        ResourcesEntity.builder().enable(inputDTO.getState()).build();
    updateEntity.setId(inputDTO.getId());
    
    resourcesRepository.updateById(updateEntity);
    
    return true;
  }
  
  @Override
  public List<ResourcesVo> button(Long parentId) {
    // 查询条件
    LambdaQueryWrapper<ResourcesEntity> queryWrapper = Wrappers.<ResourcesEntity>lambdaQuery()
        .eq(ResourcesEntity::getParentId, parentId)
        .eq(ResourcesEntity::getType, ResourcesTypeEnum.BUTTON)
        .orderByAsc(ResourcesEntity::getSort);
    // 执行查询转换类型
    return this.resourcesRepository.selectList(queryWrapper, ResourcesVo.class);
  }
  
  @Override
  public List<ResourcesTreeVo> resourcesTree() {
    // 查询全部资源列表
    List<ResourcesTreeVo> resourcesVos =
        resourcesRepository.selectList(null, ResourcesTreeVo.class);
    // 转换ITreeNode List
    List<ITreeNode<Long>> treeNodeList = new ArrayList<>(resourcesVos.size());
    treeNodeList.addAll(resourcesVos);
    // 转换树结构
    List<ITreeNode<Long>> tree = TreeUtil.listToTree(treeNodeList);
    // 转换ResourcesTreeVo List
    return ModelMapperUtil.mapList(tree, ResourcesTreeVo.class);
  }
}